<script setup lang="ts">
import {ref, reactive, computed, watch, onMounted} from 'vue'
import AppDynamicForm from '@/components/app/AppDynamicForm.vue'
import type {DynamicFormConfig, FormField, FormOption} from '@/types/fromDesign'
import {ElMessage, ElMessageBox} from "element-plus";
import {checkSaveSysForm, loadSysForm, saveSysForm} from "@/api/system";
import AppTable from "@/components/app/AppTable.vue";

defineOptions({
  name: 'FormDesign'
})

// 表单设计器状态
const previewMode = ref(false)

// 表单配置
const formConfig = reactive<DynamicFormConfig>({
  form: {
    id: 'form_' + Date.now(),
    title: '表单',
    description: '动态表单',
    fields: [],
    labelWidth: '120px',
    labelPosition: 'right',
    column: 1
  }
})

// 用于强制刷新预览的key
const previewKey = ref(0)

// JSON编辑相关
const jsonDialogVisible = ref(false)
const jsonEditMode = ref(false) // JSON编辑模式
const jsonEditContent = ref('')

// 计算属性：表单配置的JSON字符串
const formConfigJson = computed(() => {
  return JSON.stringify(formConfig, null, 2)
})

// 当前编辑的字段
const currentField = reactive<FormField>({
  id: new Date().getTime().toString(),
  type: 'text',
  label: '文本框',
  placeholder: '',
  required: false,
  defaultValue: undefined,
  span: 24,
  options: []
})

// 选项编辑对话框
const optionDialogVisible = ref(false)
const currentOptions = ref<FormOption[]>([])

// 字段类型选项
const fieldTypeOptions = [
  {value: 'text', label: '文本框'},
  {value: 'password', label: '密码框'},
  {value: 'email', label: '邮箱'},
  {value: 'number', label: '数字'},
  {value: 'textarea', label: '文本域'},
  {value: 'select', label: '下拉选择'},
  {value: 'radio', label: '单选框'},
  {value: 'checkbox', label: '复选框'},
  {value: 'checkbox-group', label: '复选框组'},
  {value: 'date', label: '日期选择'},
  {value: 'datetime', label: '日期时间'},
  {value: 'slider', label: '滑块'},
  {value: 'rate', label: '评分'},
  {value: 'switch', label: '开关'},
  {value: 'file', label: '文件上传'}
]

// 需要选项编辑的字段类型
const needsOptions = computed(() => {
  return ['select', 'radio', 'checkbox-group'].includes(currentField.type)
})

// 需要默认值输入的字段类型
const needsDefaultValueInput = computed(() => {
  return !['checkbox', 'switch', 'checkbox-group'].includes(currentField.type)
})

// 需要数组默认值的字段类型
const needsArrayDefaultValue = computed(() => {
  return ['checkbox-group'].includes(currentField.type)
})

// 需要布尔值默认值的字段类型
const needsBooleanDefaultValue = computed(() => {
  return ['checkbox', 'switch'].includes(currentField.type)
})

// 强制刷新预览
const forceRefreshPreview = () => {
  previewKey.value++
}

// 添加字段
const addField = () => {
  if (!currentField.id || !currentField.label) {
    alert('字段ID和标签不能为空')
    return
  }

  // 检查ID是否重复
  if (formConfig.form.fields.some(field => field.id === currentField.id)) {
    alert('字段ID已存在')
    return
  }

  // 处理默认值
  const fieldToAdd = {...currentField}

  // 特殊处理某些字段类型的默认值
  if (fieldToAdd.type === 'checkbox' && fieldToAdd.defaultValue === undefined) {
    fieldToAdd.defaultValue = false
  }

  if (fieldToAdd.type === 'switch' && fieldToAdd.defaultValue === undefined) {
    fieldToAdd.defaultValue = false
  }

  if (fieldToAdd.type === 'checkbox-group' && fieldToAdd.defaultValue === undefined) {
    fieldToAdd.defaultValue = []
  }

  formConfig.form.fields.push(fieldToAdd)
  resetCurrentField()
  forceRefreshPreview()
}

// 重置当前字段
const resetCurrentField = () => {
  Object.assign(currentField, {
    id: new Date().getTime().toString(),
    type: 'text',
    label: '文本框',
    placeholder: '',
    required: false,
    defaultValue: undefined,
    span: 24,
    options: []
  })


}

// 删除字段
const deleteField = (index: number) => {
  formConfig.form.fields.splice(index, 1)
  forceRefreshPreview()
}

// 编辑字段
const editField = (field: FormField) => {
  Object.assign(currentField, field)
}

// 更新字段
const updateField = () => {
  if (!currentField.id || !currentField.label) {
    alert('字段ID和标签不能为空')
    return
  }

  // 处理默认值
  const fieldToUpdate = {...currentField}

  // 特殊处理某些字段类型的默认值
  if (fieldToUpdate.type === 'checkbox' && fieldToUpdate.defaultValue === undefined) {
    fieldToUpdate.defaultValue = false
  }

  if (fieldToUpdate.type === 'switch' && fieldToUpdate.defaultValue === undefined) {
    fieldToUpdate.defaultValue = false
  }

  if (fieldToUpdate.type === 'checkbox-group' && fieldToUpdate.defaultValue === undefined) {
    fieldToUpdate.defaultValue = []
  }

  const index = formConfig.form.fields.findIndex(field => field.id === currentField.id)
  if (index !== -1) {
    formConfig.form.fields[index] = fieldToUpdate
    resetCurrentField()
    forceRefreshPreview()
  }
}

// 字段上移
const moveFieldUp = (index: number) => {
  if (index > 0) {
    const temp = formConfig.form.fields[index]
    formConfig.form.fields[index] = formConfig.form.fields[index - 1]
    formConfig.form.fields[index - 1] = temp
    forceRefreshPreview()
  }
}

// 字段下移
const moveFieldDown = (index: number) => {
  if (index < formConfig.form.fields.length - 1) {
    const temp = formConfig.form.fields[index]
    formConfig.form.fields[index] = formConfig.form.fields[index + 1]
    formConfig.form.fields[index + 1] = temp
    forceRefreshPreview()
  }
}

// 打开选项编辑对话框
const openOptionEditor = () => {
  // 每次打开对话框时都重新初始化选项数据
  if (currentField.options && currentField.options.length > 0) {
    // 深拷贝选项数据，避免直接引用导致的问题
    currentOptions.value = JSON.parse(JSON.stringify(currentField.options))
  } else {
    currentOptions.value = [{value: '', label: ''}]
  }
  optionDialogVisible.value = true
}

// 添加选项
const addOption = () => {
  currentOptions.value.push({value: '', label: ''})
}

// 删除选项
const removeOption = (index: number) => {
  currentOptions.value.splice(index, 1)
}

// 保存选项
const saveOptions = () => {
  // 过滤掉空选项
  const validOptions = currentOptions.value.filter(option => option.value && option.label)
  if (validOptions.length === 0) {
    alert('请至少添加一个有效选项')
    return
  }

  // 深拷贝选项数据，避免直接引用导致的问题
  currentField.options = JSON.parse(JSON.stringify(validOptions))

  // 如果是单选框或下拉选择，确保默认值在选项中
  if (['select', 'radio'].includes(currentField.type) && currentField.defaultValue) {
    const hasDefaultValue = validOptions.some(option => option.value == currentField.defaultValue)
    if (!hasDefaultValue) {
      // 如果默认值不在选项中，则清除默认值
      currentField.defaultValue = undefined
    }
  }

  // 如果是复选框组，确保默认值数组中的值都在选项中
  if (currentField.type === 'checkbox-group' && Array.isArray(currentField.defaultValue)) {
    const validDefaultValues = currentField.defaultValue.filter(val =>
      validOptions.some(option => option.value == val)
    )
    currentField.defaultValue = validDefaultValues
  }

  optionDialogVisible.value = false
  forceRefreshPreview()
}

// 打开JSON对话框（查看模式）
const openJsonViewer = () => {
  // 确保每次打开都显示最新数据
  jsonEditContent.value = formConfigJson.value
  jsonEditMode.value = false
  jsonDialogVisible.value = true
}

// 切换到JSON编辑模式
const switchToJsonEditMode = () => {
  // 确保编辑模式下使用最新数据
  jsonEditContent.value = formConfigJson.value
  jsonEditMode.value = true
}

// 退出JSON编辑模式
const exitJsonEditMode = () => {
  jsonEditMode.value = false
}

// 保存JSON配置
const saveJsonConfig = () => {
  try {
    const parsedConfig = JSON.parse(jsonEditContent.value)
    // 验证基本结构
    if (!parsedConfig.form) {
      alert('无效的表单配置格式')
      return
    }

    // 更新表单配置
    Object.assign(formConfig, parsedConfig)
    jsonEditMode.value = false
    forceRefreshPreview()
  } catch (e) {
    alert('JSON格式错误: ' + (e as Error).message)
  }
}

// 导出表单配置
const exportFormConfig = () => {
  const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(formConfigJson.value)
  const downloadAnchorNode = document.createElement('a')
  downloadAnchorNode.setAttribute("href", dataStr)
  downloadAnchorNode.setAttribute("download", `${formConfig.form.title || 'form'}_config.json`)
  document.body.appendChild(downloadAnchorNode)
  downloadAnchorNode.click()
  downloadAnchorNode.remove()
}

// 复制JSON到剪贴板
const copyJsonToClipboard = () => {
  navigator.clipboard.writeText(formConfigJson.value).then(() => {
    alert('JSON配置已复制到剪贴板')
  }).catch(err => {
    alert('复制失败: ' + err)
  })
}

// 表单提交处理
const handleSubmit = (data: any) => {
  console.log('表单提交数据:', data)
  alert('表单提交成功！请查看控制台输出')
}

// 表单重置处理
const handleReset = () => {
  console.log('表单已重置')
}

watch(() => currentField.type, (v) => {
  const ele = fieldTypeOptions.filter(item => item.value === v)[0];
  currentField.label = ele.label;
  currentField.id = new Date().getTime().toString();
}, {immediate: true})

onMounted(() => {
  addField()
})


// 添加一个方法来确保保存的JSON是原始格式
const getRawJsonString = (): string => {
  return JSON.stringify(formConfig, null, 2);
}
const saveCloudForm = async () => {
  // 获取原始json数据
  const rawJsonString = getRawJsonString();
  const jsonData = JSON.parse(rawJsonString);

  if (!jsonData.form.id) {
    ElMessage.error('请录入表单ID');
    return false
  }
  console.log(jsonData.form.id, jsonData.form.title, jsonData.form.description,)
  console.log(formConfigJson.value);
  let res = await checkSaveSysForm(jsonData.form.id);
  if (res.data != 0) {
    let confirmResult = await ElMessageBox.confirm('表单已存在，是否覆盖？', '提示', {
      confirmButtonText: '覆盖',
      cancelButtonText: '取消',
    })
    if (confirmResult) {
    } else {
      return false;
    }
  }
  saveSysForm({
    id: jsonData.form.id,
    title: jsonData.form.title,
    description: jsonData.form.description,
    data: formConfigJson.value
  }).then(res2 => {
    ElMessage.success('表单已保存')
  })
}

const tableRef = ref()
const formDialogVisible = ref(false)
const cloudFormDialogVisible = ref(false)
const importForm = id => {
  loadSysForm(id).then(res => {
    try {
      const parsedConfig = res.data;
      console.log(parsedConfig);
      // 应用到当前表单配置
      Object.assign(formConfig, parsedConfig);
      forceRefreshPreview();
      cloudFormDialogVisible.value = false;
      ElMessage.success('表单已导入')
    } catch (e) {
      console.error('解析表单数据失败:', e);
    }
  })
}
</script>

<template>
  <div class="form-design-container">
    <div>
      <el-card class="field-config-card">
        <el-button type="primary" @click="formDialogVisible = !formDialogVisible">表单基础设置</el-button>
        <el-button type="warning" @click="openJsonViewer">JSON配置</el-button>
        <el-button type="success"  @click="saveCloudForm">保存为云表单</el-button>
        <el-button type="danger"  @click="cloudFormDialogVisible = !cloudFormDialogVisible">云表单列表</el-button>
      </el-card>
    </div>

    <el-row :gutter="20" style="margin-top: 20px;">
      <!-- 左侧字段配置面板 -->
      <el-col :span="6">
        <el-card class="field-config-card">
          <template #header>
            <div class="card-header">
              <span>字段配置</span>
            </div>
          </template>

          <el-form label-width="80px" label-position="left">

            <el-form-item label="字段类型">
              <el-select v-model="currentField.type" placeholder="请选择字段类型"
                         style="width: 100%">
                <el-option
                  v-for="option in fieldTypeOptions"
                  :key="option.value"
                  :label="option.label"
                  :value="option.value"
                />
              </el-select>
            </el-form-item>

            <el-form-item label="字段ID">
              <el-input v-model="currentField.id" placeholder="请输入字段ID，如：username"/>
            </el-form-item>

            <el-form-item label="字段标签">
              <el-input v-model="currentField.label" placeholder="请输入字段标签，如：用户名"/>
            </el-form-item>

            <el-form-item label="占位符">
              <el-input v-model="currentField.placeholder" placeholder="请输入占位符文本"/>
            </el-form-item>

            <el-form-item label="列宽">
              <el-input v-model="currentField.span" type="number" min="0" max="24"
                        placeholder="请输入列宽"/>
            </el-form-item>

            <el-form-item label="是否必填">
              <el-switch v-model="currentField.required"/>
            </el-form-item>

            <!-- 默认值设置 -->
            <el-form-item label="默认值" v-if="needsDefaultValueInput">
              <el-input
                v-model="currentField.defaultValue"
                placeholder="请输入默认值"
              />
            </el-form-item>

            <!-- 布尔类型默认值 -->
            <el-form-item label="默认值" v-else-if="needsBooleanDefaultValue">
              <el-switch
                v-model="currentField.defaultValue"
                active-text="开启"
                inactive-text="关闭"
              />
            </el-form-item>

            <!-- 数组类型默认值 -->
            <el-form-item label="默认值" v-else-if="needsArrayDefaultValue">
              <el-select
                v-model="currentField.defaultValue"
                multiple
                placeholder="请选择默认选项"
                style="width: 100%"
                v-if="currentField.options && currentField.options.length > 0"
              >
                <el-option
                  v-for="option in currentField.options"
                  :key="option.value"
                  :label="option.label"
                  :value="option.value"
                />
              </el-select>
              <div v-else>
                请先设置选项
              </div>
            </el-form-item>

            <!-- 选项编辑 -->
            <el-form-item label="选项设置" v-if="needsOptions">
              <div>
                <div>
                  <el-button @click="openOptionEditor">编辑选项</el-button>
                </div>
                <div>
                  <div v-if="currentField.options && currentField.options.length > 0"
                       style="margin-top: 10px;">
                    <el-tag
                      v-for="(option, index) in currentField.options"
                      :key="index"
                      style="margin-right: 5px; margin-bottom: 5px;"
                    >
                      {{ option.label }}=> {{ option.value }}
                    </el-tag>
                  </div>
                </div>
              </div>
            </el-form-item>

            <el-form-item>
              <el-button type="primary" @click="addField"
                         v-if="!formConfig.form.fields.some(f => f.id === currentField.id)">
                添加字段
              </el-button>
              <el-button type="success" @click="updateField" v-else>
                更新字段
              </el-button>
              <el-button @click="resetCurrentField">重置</el-button>
            </el-form-item>
          </el-form>
        </el-card>
      </el-col>

      <!-- 中间表单预览 -->
      <el-col :span="12">
        <el-card>
          <template #header>
            <div class="card-header">
              <span>表单预览</span>
            </div>
          </template>

          <div v-if="!previewMode">
            <AppDynamicForm
              :form-config="formConfig"
              @submit="handleSubmit"
              @reset="handleReset"
            />
          </div>
        </el-card>
      </el-col>

      <!-- 右侧字段列表 -->
      <el-col :span="6">
        <el-card class="field-list-card">
          <template #header>
            <div class="card-header">
              <span>字段列表</span>
            </div>
          </template>

          <div class="field-list">
            <div
              v-for="(field, index) in formConfig.form.fields"
              :key="field.id"
              class="field-item"
            >
              <div class="field-info">
                <div class="field-label">{{ field.label }}</div>
                <div class="field-type">{{ field.type }}</div>
              </div>
              <div class="field-actions">
                <el-button
                  type="primary"
                  link
                  @click="editField(field)"
                  title="编辑"
                >
                  <el-icon>
                    <Edit/>
                  </el-icon>
                </el-button>
                <el-button
                  type="danger"
                  link
                  @click="deleteField(index)"
                  title="删除"
                >
                  <el-icon>
                    <Delete/>
                  </el-icon>
                </el-button>
                <el-button
                  type="primary"
                  link
                  :disabled="index === 0"
                  @click="moveFieldUp(index)"
                  title="上移"
                >
                  <el-icon>
                    <ArrowUp/>
                  </el-icon>
                </el-button>
                <el-button
                  type="primary"
                  link
                  :disabled="index === formConfig.form.fields.length - 1"
                  @click="moveFieldDown(index)"
                  title="下移"
                >
                  <el-icon>
                    <ArrowDown/>
                  </el-icon>
                </el-button>
              </div>
            </div>
            <div v-if="formConfig.form.fields.length === 0" class="no-fields">
              暂无字段
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 选项编辑对话框 -->
    <el-dialog v-model="optionDialogVisible" title="编辑选项" width="500px">
      <el-alert
        title="请确保每个选项都有值和标签，且不能为空"
        type="info"
        :closable="false"
        style="margin-bottom: 20px"
      />

      <el-table :data="currentOptions" style="width: 100%">
        <el-table-column label="值">
          <template #default="scope">
            <el-input v-model="scope.row.value" placeholder="选项值"/>
          </template>
        </el-table-column>
        <el-table-column label="标签">
          <template #default="scope">
            <el-input v-model="scope.row.label" placeholder="选项标签"/>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="80">
          <template #default="scope">
            <el-button
              type="danger"
              link
              @click="removeOption(scope.$index)"
              :disabled="currentOptions.length <= 1"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <el-button @click="addOption" style="margin-top: 15px">添加选项</el-button>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="optionDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="saveOptions">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- JSON配置对话框 -->
    <el-dialog v-model="jsonDialogVisible" :title="jsonEditMode ? '编辑JSON配置' : 'JSON配置'"
               width="600px" draggable>
      <el-alert
        :title="jsonEditMode ? '请确保JSON格式正确，否则可能导致表单无法正常工作' : '您可以在此处查看表单的JSON配置'"
        :type="jsonEditMode ? 'warning' : 'info'"
        :closable="false"
        style="margin-bottom: 20px"
      />

      <el-input
        v-model="jsonEditContent"
        type="textarea"
        :rows="15"
        placeholder="表单JSON配置"
        :readonly="!jsonEditMode"
      />

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="jsonDialogVisible = false">关闭</el-button>

          <!-- 查看模式下的按钮 -->
          <template v-if="!jsonEditMode">
            <el-button @click="switchToJsonEditMode">编辑</el-button>
            <el-button @click="exportFormConfig">导出</el-button>
            <el-button type="primary" @click="copyJsonToClipboard">复制</el-button>
          </template>

          <!-- 编辑模式下的按钮 -->
          <template v-else>
            <el-button @click="exitJsonEditMode">取消编辑</el-button>
            <el-button type="primary" @click="saveJsonConfig">保存</el-button>
          </template>
        </span>
      </template>
    </el-dialog>


    <!-- 表单设置对话框 -->
    <el-dialog v-model="formDialogVisible" title="表单设置"
               width="600px" draggable>
      <el-form :model="formConfig.form" label-position="left" :label-width="70">
        <el-row :gutter="20">
          <el-col :span="24">
            <el-form-item label="表单ID">
              <el-input v-model="formConfig.form.id"/>
            </el-form-item>
          </el-col>

          <el-col :span="24">
            <el-form-item label="表单标题">
              <el-input v-model="formConfig.form.title" placeholder="请输入表单标题"/>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="表单描述">
              <el-input v-model="formConfig.form.description" placeholder="请输入表单描述"/>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="标签宽度">
              <el-input v-model="formConfig.form.labelWidth" placeholder="如：120px"/>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="标签位置">
              <el-select v-model="formConfig.form.labelPosition" placeholder="请选择标签位置"
                         style="width: 100%">
                <el-option label="左侧" value="left"/>
                <el-option label="顶部" value="top"/>
                <el-option label="右侧" value="right"/>
              </el-select>
            </el-form-item>
          </el-col>

          <el-col :span="24">
            <el-form-item label="控制列数">
              <el-select v-model="formConfig.form.column" placeholder="请选择控制列"
                         style="width: 100%">
                <el-option :label="`${i}列`" v-for="i in 4" :key="i" :value="i"/>
                <el-option label="参考字段配置" value="undifine"/>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </el-dialog>


    <!-- 云表单对话框 -->
    <el-dialog v-model="cloudFormDialogVisible" title="云表单"
               draggable>
      <AppTable
        :withoutBorder="true"
        ref="tableRef"
        row-key="key"
        :btn-show="{
      add: false,
      edit: false,
      delete: false,
      export:false,
      import:false
    }"
        :pageable="false"
        api-method="get"
        api-path="/api/sys/form/list"
      >
        <template v-slot:actionBar>
        </template>
        <template v-slot:tableColumn>
          <el-table-column prop="id" label="ID" align="left"/>
          <el-table-column prop="title" label="名称" align="left"/>
          <el-table-column prop="description" label="描述" align="left"/>
          <el-table-column fixed="right" label="操作" width="250">
            <template #default="scope">
              <el-button link type="primary" size="small" icon="Edit"
                         @click="importForm(scope.row.id)">
                导入编辑器
              </el-button>
            </template>
          </el-table-column>
        </template>
      </AppTable>
    </el-dialog>


  </div>
</template>

<style scoped>

:deep(.el-collapse-item__header) {
  padding-left: 20px;
  font-weight: 500;
  color: #606266;
}

:deep(.el-collapse-item__content) {
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}


.form-design-container {
  padding: 20px;
  background-color: #f5f5f5;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.form-settings-card {
  margin-bottom: 20px;
}

.field-config-card,
.field-list-card {
  margin-bottom: 20px;
}

.field-list {
  max-height: calc(100vh - 450px);
  overflow-y: auto;
}

.field-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  border-bottom: 1px solid #ebeef5;
}

.field-item:last-child {
  border-bottom: none;
}

.field-info {
  flex: 1;
}

.field-label {
  font-weight: bold;
  margin-bottom: 4px;
}

.field-type {
  font-size: 12px;
  color: #999;
}

.field-actions {
  display: flex;
  gap: 5px;
}

.no-fields {
  text-align: center;
  padding: 20px;
  color: #999;
}
</style>
